package com.cnsuning.jobtool.jobtools.mycat.generator.prd.new2;

import com.cnsuning.jobtool.utils.ExcelUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ConfigXmlGeneratorSub {

    public static final String LOGIC_DB_NAME = "OMSDDB";
    /**
     * 总库数，默认64
     */
    private int totalDbNum = 64;

    /**
     * 单个组数据库个数
     */
    private int singleDbNum = 32;

    /**
     * 每个库分表个数,默认32
     */
    private int subTableNum = 32;

    /**
     * 分库算法
     */
    private String dbRule = "ROUTE_DB";

    /**
     * 分表算法
     */
    private String tableRule = "ROUTE_TABLE";

    /**
     * 配置文件路径
     */
    private String excelConfigPath = "src/main/java/com/cnsuning/jobtool/jobtools/mycat/generator/prd/files/new2/config.xlsx";

    /**
     * 分表配置模板路径
     */
    private String subTableTemplatePath = "src/main/java/com/cnsuning/jobtool/jobtools/mycat/generator/prd/files/new2/SUB_TABLE_TEMPLATE.txt";


    /**
     * 最终生成文件路径
     */
    private String targetPath = "src/main/java/com/cnsuning/jobtool/jobtools/mycat/generator/prd/files/new2/schema.xml";


    private DecimalFormat tableDf = new DecimalFormat("0000");
    private DecimalFormat dnDf = new DecimalFormat("000");
    private String dataNodeStr = "bizMysqlDn_$" + (dnDf.format(0)) + "-" +(dnDf.format(totalDbNum-1));
    private String subTablesStr = "%s_$" +  (tableDf.format(0)) + "-" + (tableDf.format(singleDbNum * subTableNum));

    /**
     * 分表模板
     */
    public final String TABLE_TEMPLATE = "\t\t<table name=\"%s\" dataNode=\""+dataNodeStr+"\" subTables=\""+subTablesStr+"\" rule=\"%s\"/>\n";

    public static final String HEAD_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<!DOCTYPE mycat:schema SYSTEM \"schema.dtd\">\n" +
            "<mycat:schema xmlns:mycat=\"http://io.mycat/\">\n";

    public static final String FOOT_TEMPLATE = "</mycat:schema>";
    /**
     *
     * @param tableConfig 键：表名  值：路由字段
     */
    private void generateTables(List<Map<String, String>> tableConfig) throws IOException {
        if (CollectionUtils.isEmpty(tableConfig)) return;
        File targetFile = new File(targetPath);
        for (Map<String, String> rowData : tableConfig)
        {
            for (Map.Entry<String, String> entry : rowData.entrySet()){
                String tableName = entry.getKey();
                String routerName = entry.getValue();
//                System.out.println(TABLE_TEMPLATE);
                String tableStr = String.format(TABLE_TEMPLATE,tableName,tableName,tableRule);
                FileUtils.writeStringToFile(targetFile,tableStr,"utf-8",true);
                List<String> subTableTempLateList = FileUtils.readLines(new File(subTableTemplatePath), "utf-8");
                for (String subTableTempLate: subTableTempLateList){
                    String subTableStr = String.format(subTableTempLate+"\n",tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,
                            tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,tableName,
                            tableName,tableName,tableName,tableName,tableName,dbRule);
                    FileUtils.writeStringToFile(targetFile,subTableStr,"utf-8",true);
                }
                FileUtils.writeStringToFile(targetFile,"\n","utf-8",true);
                subTableTempLateList = null;
            }
        }
    }

    /**
     * 生成datanode和datahost配置
     * @param dbsConfig
     * @throws IOException
     * @throws InvalidFormatException
     */
    private void generateDN(List<Map<String, String>> dbsConfig) throws IOException, InvalidFormatException {
        if (CollectionUtils.isEmpty(dbsConfig)) return;
        File targetFile = new File(targetPath);
//        for (Map<String, String> rowData : dbsConfig)
        //生成datanode
        for (int i =0 ; i < dbsConfig.size(); i ++)
        {
            Map<String, String> rowData = dbsConfig.get(i);
            for (Map.Entry<String, String> entry : rowData.entrySet()){
                String database = entry.getKey();
                String vip = entry.getValue();
//                <dataNode name="bizMysqlDn_000" dataHost="data_host1" database="omsddb_001"/>
                String  dnStr = String.format("\t<dataNode name=\"bizMysqlDn_"+dnDf.format(i)+"\" dataHost=\"data_host"+(i+1)+"\" database=\"%s\"/>\n",database);
                FileUtils.writeStringToFile(targetFile,dnStr,"utf-8",true);
            }
        }

        //生成datahost
        for (int i =0 ; i < dbsConfig.size(); i ++)
        {
            Map<String, String> rowData = dbsConfig.get(i);
            for (Map.Entry<String, String> entry : rowData.entrySet()){
                String database = entry.getKey();
                String vip = entry.getValue();
//                <dataNode name="bizMysqlDn_000" dataHost="data_host1" database="omsddb_001"/>
                String  dnStr = String.format("\t<dataHost name=\"data_host"+(i+1)+"\" maxCon=\"100\" minCon=\"10\" balance=\"0\" writeType=\"0\" dbType=\"mysql\" dbDriver=\"native\" switchType=\"1\" slaveThreshold=\"100\">\n" +
                        "\t\t<heartbeat>select user();</heartbeat>\n" +
                        "\t\t<writeHost host=\"host"+(i+1)+"\" url=\""+vip+":3306\"/>\n" +
                        "\t</dataHost>\n",database);
                FileUtils.writeStringToFile(targetFile,dnStr,"utf-8",true);
            }
        }
    }


    @Test
    public void generate() throws IOException, InvalidFormatException {
            File targetFile = new File(targetPath);
        if (targetFile.exists())
        {
            targetFile.delete();
            targetFile.createNewFile();
        }


        File configFile = new File(excelConfigPath);
        //header
        FileUtils.writeStringToFile(targetFile,HEAD_TEMPLATE,"utf-8");

        //table配置
        FileUtils.writeStringToFile(targetFile,String.format("\t<schema name=\"%s\" checkSQLschema=\"true\" >\n",LOGIC_DB_NAME),"utf-8",true);

        List<List<Object>> tableDataList = ExcelUtils.readExcelNoTitleOneSheet(configFile, "tables");
        List<Map<String, String>> tableConfig = new ArrayList<>();
        for (List<Object> rowData : tableDataList)
        {
            Map<String,String> row = new HashMap<>();
            row.put(rowData.get(0)+"",rowData.get(1)+"");
            tableConfig.add(row);
        }
        generateTables(tableConfig);
        FileUtils.writeStringToFile(targetFile,"\t</schema>\n\n","utf-8",true);

        //datenode
        List<List<Object>> dbsDataList = ExcelUtils.readExcelNoTitleOneSheet(configFile, "dbs");
        List<Map<String, String>> dbsConfig = new ArrayList<>();
        for (List<Object> rowData : dbsDataList)
        {
            Map<String,String> row = new HashMap<>();
            row.put(rowData.get(0)+"",rowData.get(1)+"");
            dbsConfig.add(row);
        }
        generateDN(dbsConfig);

        //foot
        FileUtils.writeStringToFile(targetFile,FOOT_TEMPLATE,"utf-8",true);
    }
}
